package org.swift.commons.deployer.utils;

import java.util.Map;

import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.OperationContext;
import org.apache.axis2.description.AxisEndpoint;
import org.apache.axis2.description.TransportInDescription;
import org.apache.axis2.description.WSDL2Constants;
import org.apache.axis2.engine.AxisConfiguration;

public class AxisServiceUtil {

	private final static AxisServiceUtil instance = new AxisServiceUtil();

	public static AxisServiceUtil instance() {
		return instance;
	}
	
	public String getCurrentServiceName() {
		MessageContext messageContext = MessageContext
			.getCurrentMessageContext();
		return messageContext.getServiceContext().getAxisService().getName();
	}

	@SuppressWarnings("unchecked")
	public String getBaseURL() {
		/**
		 * Just a note:
		 * We can use this to find the REST endpoint if necessary:
		 * 		endpoint.getBinding().getType().equals(WSDL2Constants.URI_WSDL2_HTTP)
		 */
		MessageContext messageContext = MessageContext
			.getCurrentMessageContext();
		
		// Use the same endpoint the user used to issue the request
		AxisEndpoint axisEndpoint =
            (AxisEndpoint) messageContext.getProperty(WSDL2Constants.ENDPOINT_LOCAL_NAME);
		if (axisEndpoint != null){
			return getEndpointUrl(axisEndpoint);
		}
		
		// If that fails... let's just pull out the first endpoint we know is
		// available and use that.
		Map endpoints = messageContext.getServiceContext().getAxisService().getEndpoints();
		if (endpoints.size() > 0) {
			AxisEndpoint endpoint = (AxisEndpoint)endpoints.values().iterator().next();
			return getEndpointUrl(endpoint);
		}
		
		AxisConfiguration configuration = messageContext
			.getConfigurationContext().getAxisConfiguration();
		
		TransportInDescription inDescription = configuration
			.getTransportIn("http");

		EndpointReference[] eprs;
		try {
			eprs = inDescription.getReceiver().getEPRsForService(
				messageContext.getAxisService().getName(), null);
		} catch (AxisFault e) {
			// I don't want to have to catch this configuration error
			throw new RuntimeException(e);
		}
		return eprs[0].getAddress();
	}
	
	private String getEndpointUrl(AxisEndpoint endpoint){
		endpoint.setEndpointURL(null);
		return endpoint.getEndpointURL();
	}

	public void setResponseContentType(String contentType) throws AxisFault {
		MessageContext messageContext = MessageContext
			.getCurrentMessageContext();
		OperationContext operationContext = messageContext
			.getOperationContext();
		MessageContext outMessageContext = operationContext
			.getMessageContext(WSDL2Constants.MESSAGE_LABEL_OUT);
		// responseFormat is the content type of the outgoing message
		outMessageContext.setProperty(Constants.Configuration.MESSAGE_TYPE,
			contentType);
	}

}
